<template>
  <div style="overflow-x: hidden;">
    <n-card>
      <template #header>
        <div style="display: flex; justify-content: space-between; align-items: center;">
          <span style="font-size: 16px; font-weight: 600;">MCP工具管理</span>
          <div style="display: flex; align-items: center; gap: 12px;">
            <n-input-group style="display: flex; align-items: center; height: 36px;">
              <n-input 
                v-model:value="searchName" 
                placeholder="搜索MCP名称..." 
                style="width: 200px; height: 36px;" 
                @keyup.enter="fetchData(1)"
                clearable
              />
              <n-button size="medium" @click="fetchData(1)" style="height: 36px;">
                <n-icon size="16">
                  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128c0-70.7 57.2-128 128-128c70.7 0 128 57.2 128 128c0 70.7-57.2 128-128 128z" fill="currentColor"></path></svg>
                </n-icon>
              </n-button>
            </n-input-group>
            <n-button type="default" size="medium" @click="refreshTools" title="刷新工具列表">
              <n-icon size="16">
                <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M3 21v-5h5"></path></g></svg>
              </n-icon>
              刷新工具
            </n-button>
            <n-button type="primary" size="medium" @click="showAddModal = true">新增MCP</n-button>
          </div>
        </div>
      </template>
      <n-data-table
        :columns="columns"
        :data="tableData"
        :pagination="pagination"
        :loading="loading"
        :row-key="row => row.id"
        @update:page="fetchData"
        :bordered="false"
        :single-line="false"
        size="medium"
        :striped="true"
      />
      <n-modal v-model:show="showAddModal" title="新增MCP" preset="dialog">
        <n-form :model="form" :rules="rules" ref="formRef">
          <n-form-item label="描述" path="description">
            <n-input v-model:value="form.description" placeholder="请输入描述" />          
          </n-form-item>
          <n-form-item label="是否启用" path="enable">
            <n-switch v-model:value="form.enable" :checked-value="1" :unchecked-value="0" />          
          </n-form-item>
          <n-form-item label="配置JSON" path="configJson">
            <n-input v-model:value="form.configJson" type="textarea" placeholder="请输入配置JSON" :rows="10" @update:value="updateConfigJson" />
            <template #feedback>
              <div style="font-size: 12px; color: #999;">示例: {"mcpServers": {"amap-amap-sse": {"url": "https://mcp.amap.com", "type": "sse", "sseEndpoint": "/sse?key=0c3ee577f67cf20b52aadee50601b3c8"}}}</div>
            </template>
          </n-form-item>
          <!-- 移除状态选择，将根据测试结果自动设置 -->
        </n-form>
        <template #action>
          <n-button @click="showAddModal = false">取消</n-button>
          <n-button type="primary" @click="handleAdd">确定</n-button>
        </template>
      </n-modal>
      <n-modal v-model:show="showEditModal" title="编辑MCP" preset="dialog">
        <n-form :model="form" :rules="rules" ref="formRef">
          <n-form-item label="描述" path="description">
            <n-input v-model:value="form.description" placeholder="请输入描述" />          
          </n-form-item>
          <n-form-item label="是否启用" path="enable">
            <n-switch v-model:value="form.enable" :checked-value="1" :unchecked-value="0" />          
          </n-form-item>
          <n-form-item label="配置JSON" path="configJson">
            <n-input v-model:value="formattedJson" type="textarea" placeholder="请输入配置JSON" :rows="10" @update:value="updateConfigJson" />
          </n-form-item>
          <!-- 移除状态选择，将根据测试结果自动设置 -->
        </n-form>
        <template #action>
          <n-button @click="showEditModal = false">取消</n-button>
          <n-button type="primary" @click="handleEdit">保存</n-button>
        </template>
      </n-modal>
      <n-modal v-model:show="showToolsModal" preset="dialog" style="width: 800px;">
        <template #header>
          <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
            <div style="font-size: 16px; font-weight: 600;">{{ currentMcpName }}的工具列表</div>
            <div style="display: flex; align-items: center; gap: 12px;">
              <n-tag type="info" size="small">工具总数: {{ toolsData.toolCount || 0 }}</n-tag>
            </div>
          </div>
        </template>
        <div v-if="toolsLoading" style="text-align: center; padding: 20px;">
          <n-spin size="large" />
        </div>
        <div v-else style="max-height: 500px; overflow-y: auto;">
          
          <!-- 使用虚拟列表实现动态插入行展示参数 -->
          <div v-for="tool in toolsData.tools" :key="tool.name">
            <div style="display: flex; padding: 8px 0; border-bottom: 1px solid #f0f0f0; cursor: pointer;" 
                 :style="{ backgroundColor: expandedToolId === tool.name ? '#f5f5f5' : 'transparent' }" 
                 @click="toggleToolExpansion(tool)">
              <div style="width: 200px; padding-left: 12px; font-weight: 500; flex-shrink: 0;">{{ tool.name }}</div>
              <div style="flex: 1; padding-right: 12px; color: #666;">
                <n-tooltip trigger="hover" placement="top">
                  <template #trigger>
                    <span style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 100%; display: inline-block;">
                      {{ tool.description }}
                    </span>
                  </template>
                  <template #default>
                    <div style="max-width: 500px; word-break: break-all; white-space: normal;">
                      {{ tool.description }}
                    </div>
                  </template>
                </n-tooltip>
              </div>
            </div>
            
            <!-- 动态展开的参数详情行 -->
            <div v-if="expandedToolId === tool.name" style="padding: 12px 12px 12px 212px; background-color: #fafafa; border-left: 3px solid #1890ff;">
              <div style="font-weight: bold; margin-bottom: 8px; color: #333;">
                参数详情 - {{ tool.name }}
              </div>
              <pre style="margin: 0; white-space: pre-wrap; word-break: break-all; font-size: 12px; color: #666; font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;">
{{ formatJsonSchema(tool.inputSchema) }}
              </pre>
            </div>
          </div>
        </div>
      </n-modal>
    </n-card>
  </div>
</template>

<script setup>
import { h, ref, reactive, onMounted, computed, onUnmounted } from 'vue'
import { NCard, NDataTable, NButton, NInput, NModal, NForm, NFormItem, NSelect, NTag, NSpin, useMessage, NIcon, NTooltip, NSwitch, NInputGroup } from 'naive-ui'
import { EyeOutline, CreateOutline, TrashOutline, RefreshOutline } from '@vicons/ionicons5'
import { mcpService } from '../../shared/services/mcp-service'

const message = useMessage()
const loading = ref(false)
const tableData = ref([])
const pagination = reactive({ 
  page: 1, 
  pageSize: 15, 
  itemCount: 0, 
  showSizePicker: true,
  pageSizes: [10, 15, 20, 50],
  showQuickJumper: true
})
const searchName = ref('')
const showAddModal = ref(false)
const showEditModal = ref(false)
const showToolsModal = ref(false)
const toolsLoading = ref(false)
const toolsData = ref({ tools: [], toolCount: 0 })
const expandedToolId = ref(null) // 当前展开的工具ID
const currentMcpName = ref('') // 添加当前选中的MCP名称
const form = reactive({ id: null, description: '', configJson: '', enable: 1 }) // 添加enable字段，默认为1(启用)
const formRef = ref(null)
const rules = {
  description: { required: false },
  configJson: { 
    required: true, 
    message: '请输入配置JSON', 
    trigger: 'blur',
    validator: (rule, value) => {
      if (!value) return new Error('请输入配置JSON')
      try {
        const jsonObj = JSON.parse(value)
        if (!jsonObj.mcpServers || Object.keys(jsonObj.mcpServers).length === 0) {
          return new Error('JSON格式不正确，必须包含mcpServers字段')
        }
        return true
      } catch (e) {
        return new Error('JSON格式不正确: ' + e.message)
      }
    }
  }
  // 移除状态验证规则，因为将根据测试结果自动设置
}

// 格式化JSON的计算属性
const formattedJson = computed({
  get: () => {
    try {
      if (!form.configJson) return ''
      const jsonObj = JSON.parse(form.configJson)
      return JSON.stringify(jsonObj, null, 2) // 使用2个空格缩进
    } catch (e) {
      return form.configJson // 如果解析失败，返回原始内容
    }
  },
  set: (val) => {
    form.configJson = val
  }
})

// 更新configJson，尝试将输入格式化为紧凑的JSON
function updateConfigJson(val) {
  try {
    const jsonObj = JSON.parse(val)
    form.configJson = JSON.stringify(jsonObj)
  } catch (e) {
    form.configJson = val // 如果解析失败，保存原始输入
  }
}
const typeOptions = [
  { label: 'sse', value: 'sse' },
  { label: 'STDIO', value: 'STDIO' }
]
const statusOptions = [
  { label: '可用', value: 1 },
  { label: '不可用', value: 0 }
]
const columns = [
  { title: 'ID', key: 'id', width: 80 },
  { 
    title: '名称', 
    key: 'name', 
    width: 200, 
    render(row) { 
      return h('div', { style: 'display: flex; align-items: center; gap: 8px;' }, [
        h('div', { 
          style: {
            width: '10px',
            height: '10px',
            borderRadius: '50%',
            backgroundColor: row.status === 1 ? '#52c41a' : '#ff4d4f'
          }
        }),
        row.name
      ])
    } 
  },
  { title: '类型', key: 'contentType', width: 100 },
  { title: '描述', key: 'description', ellipsis: { tooltip: true } },
  { 
    title: '是否启用', 
    key: 'enable', 
    width: 120, 
    render(row) { 
      return h(NSwitch, { 
        value: row.enable === 1, 
        'onUpdate:value': (value) => handleEnableChange(row.id, value ? 1 : 0) 
      }) 
    } 
  },
  { title: '更新时间', key: 'updateTime', width: 220 },
  { 
    title: '操作', 
    key: 'actions', 
    width: 120, 
    render(row) { 
      return h('div', { style: 'display: flex; gap: 8px;' }, [
        h(NTooltip, { trigger: 'hover' }, {
          trigger: () => h(NButton, { 
            size: 'small', 
            quaternary: true,
            disabled: row.status !== 1,
            onClick: () => openTools(row) 
          }, {
            default: () => h(NIcon, { size: 16 }, () => h(EyeOutline))
          }),
          default: () => row.status === 1 ? '查看工具' : '服务不可用'
        }),
        h(NTooltip, { trigger: 'hover' }, {
          trigger: () => h(NButton, { 
            size: 'small', 
            quaternary: true,
            type: 'primary',
            onClick: () => reconnectServer(row) 
          }, {
            default: () => h(NIcon, { size: 16 }, () => h(RefreshOutline))
          }),
          default: () => '重连服务'
        }),
        h(NTooltip, { trigger: 'hover' }, {
          trigger: () => h(NButton, { 
            size: 'small', 
            quaternary: true,
            onClick: () => openEdit(row) 
          }, {
            default: () => h(NIcon, { size: 16 }, () => h(CreateOutline))
          }),
          default: () => '编辑'
        }),
        h(NTooltip, { trigger: 'hover' }, {
          trigger: () => h(NButton, { 
            size: 'small', 
            quaternary: true,
            type: 'error',
            onClick: () => handleDelete(row) 
          }, {
            default: () => h(NIcon, { size: 16 }, () => h(TrashOutline))
          }),
          default: () => '删除'
        })
      ])
    }
  }
]
const toolsColumns = [
  { title: '工具名称', key: 'name', width: 200 },
  { title: '描述', key: 'description', ellipsis: { tooltip: true } }
]

function fetchData(page = 1) {
  loading.value = true
  mcpService.getMcpPage(searchName.value, page, pagination.pageSize).then(res => {
    if (res.code === 0) {
      tableData.value = res.data.records || []
      pagination.page = res.data.current
      pagination.itemCount = res.data.total
    } else {
      message.error(res.msg || '获取数据失败')
    }
  }).finally(() => loading.value = false)
}

function openTools(row) {
  currentMcpName.value = row.name 
  console.log("当前行",currentMcpName.value)
  showToolsModal.value = true
  toolsLoading.value = true
  toolsData.value = { tools: [], toolCount: 0 }
  expandedToolId.value = null // 重置展开状态
  
  mcpService.getMcpToolsByName(row.name).then(res => {
    if (res.code === 0) {
      toolsData.value = res.data
    } else {
      message.error(res.msg || '获取工具列表失败')
    }
  }).catch(err => {
    message.error('获取工具列表失败: ' + err.message)
  }).finally(() => {
    toolsLoading.value = false
  })
}

// 切换工具展开状态
function toggleToolExpansion(row) {
  if (expandedToolId.value === row.name) {
    expandedToolId.value = null // 如果已展开则收起
  } else {
    expandedToolId.value = row.name // 展开当前工具
  }
}

// 格式化JSON Schema显示
function formatJsonSchema(schema) {
  try {
    if (typeof schema === 'string') {
      const parsed = JSON.parse(schema)
      return JSON.stringify(parsed, null, 2)
    } else if (typeof schema === 'object') {
      return JSON.stringify(schema, null, 2)
    }
    return String(schema)
  } catch (e) {
    return String(schema)
  }
}

function handleAdd() {
  formRef.value?.validate(errors => {
    if (!errors) {
      try {
        // 验证JSON格式
        const jsonObj = JSON.parse(form.configJson)
        if (!jsonObj.mcpServers || Object.keys(jsonObj.mcpServers).length === 0) {
          message.error('JSON格式不正确，必须包含mcpServers字段')
          return
        }
        
        // 传递描述、JSON配置和启用状态
        const submitData = {
          description: form.description,
          configJson: form.configJson,
          enable: form.enable
        }
        
        mcpService.addMcp(submitData).then(res => {
          if (res.code === 0) {
            message.success('新增成功')
            showAddModal.value = false
            fetchData(1)
          } else {
            message.error(res.msg || '新增失败')
          }
        })
      } catch (e) {
        message.error('JSON格式不正确: ' + e.message)
      }
    }
  })
}

function openEdit(row) {
  Object.assign(form, row)
  // 确保enable字段存在
  if (form.enable === undefined) {
    form.enable = 1
  }
  showEditModal.value = true
  // 编辑时自动格式化JSON
  try {
    if (form.configJson) {
      const jsonObj = JSON.parse(form.configJson)
      form.configJson = JSON.stringify(jsonObj)
    }
  } catch (e) {
    // 如果解析失败，保持原样
    message.warning('JSON格式解析失败，请检查格式')
  }
}

function handleEdit() {
  formRef.value?.validate(errors => {
    if (!errors) {
      try {
        // 验证JSON格式
        const jsonObj = JSON.parse(form.configJson)
        if (!jsonObj.mcpServers || Object.keys(jsonObj.mcpServers).length === 0) {
          message.error('JSON格式不正确，必须包含mcpServers字段')
          return
        }
        
        // 传递必要字段和启用状态
        const submitData = {
          id: form.id,
          description: form.description,
          configJson: form.configJson,
          enable: form.enable
        }
        
        mcpService.updateMcp(form.id, submitData).then(res => {
          if (res.code === 0) {
            message.success('修改成功')
            showEditModal.value = false
            fetchData(pagination.page)
          } else {
            message.error(res.msg || '修改失败')
          }
        })
      } catch (e) {
        message.error('JSON格式不正确: ' + e.message)
      }
    }
  })
}

function handleDelete(row) {
  message.info('正在删除...')
  mcpService.deleteMcp(row.id).then(res => {
    if (res.code === 0) {
      message.success('删除成功')
      fetchData(1)
    } else {
      message.error(res.msg || '删除失败')
    }
  })
}

function refreshTools() {
  message.info('正在刷新工具列表...')
  
  mcpService.refreshMcpTools().then(res => {
    if (res.code === 0) {
      message.success('工具列表已刷新')
      fetchData(1) // 刷新后重新加载数据
    } else {
      message.error(res.msg || '刷新失败')
    }
  }).catch(err => {
    message.error('刷新失败: ' + err.message)
  })
}

let pollingInterval = null

onMounted(() => {
  fetchData(1)
  // 启动定时轮询，20秒更新一次状态
  pollingInterval = setInterval(() => {
    refreshStatus()
  }, 20000)
})

onUnmounted(() => {
  // 清除定时器
  if (pollingInterval) {
    clearInterval(pollingInterval)
  }
})

// 处理启用状态变更
function handleEnableChange(id, enable) {
  message.info('正在更新启用状态...')
  // 调用API更新启用状态
  mcpService.updateMcpEnableStatus({"id":id,"enable":enable}).then(res => {
    if (res.code === 0) {
      message.success('更新成功')
      // 刷新数据
      fetchData(pagination.page)
    } else {
      message.error(res.msg || '更新失败')
    }
  }).catch(err => {
    message.error('更新失败: ' + err.message)
  })
}

// 重连指定MCP服务
function reconnectServer(row) {
  message.loading(`正在重连 ${row.name}...`, { duration: 0 })
  mcpService.reconnectMcp(row.name)
    .then(res => {
      message.destroyAll() // 清除所有消息提示
      if (res.code === 0) {
        message.success(res.data || `重连成功: ${row.name}`)
        // 重连成功后刷新表格
        fetchData(pagination.page)
      } else {
        message.error(res.msg || `重连失败: ${row.name}`)
      }
    })
    .catch(err => {
      message.destroyAll() // 清除所有消息提示
      message.error('重连失败: ' + err.message)
    })
}

function refreshStatus() {
  mcpService.getMcpPage(searchName.value, pagination.page, pagination.pageSize).then(res => {
    if (res.code === 0 && res.data.records) {
      // 局部更新状态，保持其他数据不变
      res.data.records.forEach(newRow => {
        const existingRow = tableData.value.find(row => row.id === newRow.id)
        if (existingRow) {
          existingRow.status = newRow.status
        }
      })
    }
  }).catch(() => {
    // 静默处理错误，不影响用户体验
  })
}
</script>
